package com.avalon.shop.service;

import com.avalon.core.exception.AvalonException;
import com.avalon.core.model.RecordRow;
import com.avalon.core.util.BCryptUtil;
import com.avalon.core.util.JacksonUtil;
import com.avalon.core.util.ObjectUtils;
import com.avalon.core.util.RestTemplateUtils;
import com.avalon.shop.ShopContext;
import lombok.extern.slf4j.Slf4j;
import com.avalon.shop.config.ShopConfig;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@Service
@Slf4j
public class ShopService {
    private final ShopContext shopContext;
    private final ShopConfig shopConfig;
    private String token;

    public ShopService(ShopContext shopContext, ShopConfig shopConfig) {
        this.shopContext = shopContext;
        this.shopConfig = shopConfig;
    }

    public RecordRow login(String username, String password) {
        log.info("login: username={}, password={}", username, password);
        HashMap<String, Object> param = new HashMap<>();
        param.put("fields", "id");
        param.put("serviceName", "pet.user");
        param.put("rpnCondition", "(&,(=,phone," + username + "),(=,password," + password + "))");
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        headers.put("token", token);
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(shopConfig.getServer() + "/model/get/one",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            RecordRow recordRow = JacksonUtil.convert2Map(responseEntity.getBody());
            if (recordRow.isEmpty()) {
                throw new AvalonException("用户或密码错误,请重新输入");
            }
            recordRow.put("token", BCryptUtil.simpleUUID());
            return recordRow;
        }
        throw new AvalonException("用户或密码错误,请重新输入");
    }


    public void backLogin() {
        HashMap<String, Object> param = new HashMap<>();
        param.put("username", shopConfig.getUserName());
        param.put("password", shopConfig.getPassword());
        param.put("db", shopConfig.getDb());
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(shopConfig.getServer() + "/login",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            RecordRow recordRow = JacksonUtil.convert2Map(responseEntity.getBody());
            if (recordRow.isEmpty()) {
                log.error("用户或密码错误,请重新输入");
                throw new AvalonException("用户或密码错误,请重新输入");
            }
            log.info("{},登录成功", shopConfig.getUserName());
            token = recordRow.getString("token");
            shopContext.setBackToken(token);
        } else {
            log.error("用户或密码错误,请重新输入");
            throw new AvalonException("用户或密码错误,请重新输入");
        }
    }

    public boolean validateLogin() {
        if (ObjectUtils.isNull(shopContext.getBackToken())) {
            return false;
        }
        HashMap<String, Object> param = new HashMap<>();
        param.put("token", shopContext.getBackToken());
        Map<String, String> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("Accept", MediaType.toString(Arrays.asList(MediaType.APPLICATION_JSON)));
        ResponseEntity<String> responseEntity = RestTemplateUtils.post(shopConfig.getServer() + "/validate",
                headers, param, String.class);
        if (responseEntity.getStatusCode().is2xxSuccessful()) {
            return true;
        }
        log.error("token {},无效,请重新登录", shopContext.getBackToken());
        return false;
    }
}
